package com.karrysong.blog_springboot.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.karrysong.blog_springboot.entity.Article;
import com.karrysong.blog_springboot.entity.ArticleTag;
import com.karrysong.blog_springboot.entity.Category;
import com.karrysong.blog_springboot.entity.Tag;
import com.karrysong.blog_springboot.enums.ErrorCode;
import com.karrysong.blog_springboot.mapper.ArticleMapper;
import com.karrysong.blog_springboot.mapper.ArticleTagMapper;
import com.karrysong.blog_springboot.mapper.TagMapper;
import com.karrysong.blog_springboot.service.TagService;
import com.karrysong.blog_springboot.vo.CategoryVo;
import com.karrysong.blog_springboot.vo.Result;
import com.karrysong.blog_springboot.vo.TagVo;
import com.karrysong.blog_springboot.vo.params.CategoryParam;
import com.karrysong.blog_springboot.vo.params.TagPage;
import com.karrysong.blog_springboot.vo.params.TagParam;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.*;

/**
 * @ClassName: TagServiceImpl
 * @Author: KarrySong
 * @Date: 2022/8/4 9:38
 * @Description:
 */
@Service
public class TagServiceImpl implements TagService {

    @Autowired
    private TagMapper tagMapper;
    @Autowired
    private ArticleTagMapper articleTagMapper;
    @Autowired
    private ArticleMapper articleMapper;

    public TagVo copy(Tag tag){
        TagVo tagVo = new TagVo();
        BeanUtils.copyProperties(tag,tagVo);
        return tagVo;
    }

    public List<TagVo> copyList(List<Tag> tagList){
        List<TagVo> tagVoList = new ArrayList<>();
        for (Tag tag : tagList) {
            tagVoList.add(copy(tag));
        }
        return tagVoList;
    }

    @Override
    public List<TagVo> hot(int limit) {

        List<Long> hotsTagIds = tagMapper.findHotsTagIds(limit);
        if (CollectionUtils.isEmpty(hotsTagIds)){
            return Collections.emptyList();
        }
        List<Tag> tagList = tagMapper.findTagsByTagIds(hotsTagIds);
        return copyList(tagList);
    }

    @Override
    public Result findAll() {
        List<Tag> tags = tagMapper.selectList(new LambdaQueryWrapper<>());
        return Result.success(copyList(tags));
    }

    @Override
    public List<TagVo> findTagsByArticleId(Long id) {
        /*LambdaQueryWrapper<ArticleTag> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(ArticleTag::getArticleId, id);
        List<ArticleTag> articleTags = articleTagMapper.selectList(lambdaQueryWrapper);

        LambdaQueryWrapper<Tag> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Tag::getId)*/

        //mybatisplus 无法进行多表查询
        List<Tag> tags = tagMapper.findTagsByArticleId(id);
        return copyList(tags);

    }


    @Override
    public Result findDetailById(Long id) {
        Tag tag = tagMapper.selectById(id);
        return Result.success(copy(tag));
    }

    @Override
    public Result getTags(TagPage tagPage) {
        Page<Tag> page = new Page<>(tagPage.getPage(), tagPage.getPageSize());
        LambdaQueryWrapper<Tag> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Strings.isNotEmpty(tagPage.getTagName()), Tag::getTagName, tagPage.getTagName());
        IPage<Tag> pageResult = tagMapper.selectPage(page, wrapper);
        List<Tag> records = pageResult.getRecords();
        List<TagVo> articleVoList = copyList(records);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("tagList", articleVoList);
        jsonObject.put("pageData", pageResult);
        return Result.success(jsonObject);
    }

    @Override
    public Result updateTag(TagParam tagParam) {

        //判断是否重复
        LambdaQueryWrapper<Tag> tagWrapper = new LambdaQueryWrapper<>();
        tagWrapper.eq(Strings.isNotEmpty(tagParam.getTagName()), Tag::getTagName, tagParam.getTagName());
        List<Tag> tags = tagMapper.selectList(tagWrapper);
        if (tags != null && tags.size() > 0){
            //重复
            return  Result.fail(ErrorCode.ADMIN_ERROR, "信息重复");
        }

        Tag tag = new Tag();
        tag.setId(tagParam.getId());
        if (tagParam.getTagName() != null){
            tag.setTagName(tagParam.getTagName());
        }
        if (tagParam.getAvatar() != null){
            tag.setAvatar(tagParam.getAvatar());
        }
        int i = tagMapper.updateById(tag);
        if (i > 0){
            return Result.success(null);
        }else {
            return Result.fail(ErrorCode.ADMIN_ERROR, "修改标签失败");
        }

    }

    @Override
    public Result addTag(TagParam tagParam) {
        //判断是否重复
        LambdaQueryWrapper<Tag> tagWrapper = new LambdaQueryWrapper<>();
        tagWrapper.eq(Strings.isNotEmpty(tagParam.getTagName()), Tag::getTagName, tagParam.getTagName());
        List<Tag> tags = tagMapper.selectList(tagWrapper);
        if (tags != null && tags.size() > 0){
            //重复
            return  Result.fail(ErrorCode.ADMIN_ERROR, "信息重复");
        }

        Tag tag = new Tag();
        if (tagParam.getTagName() != null){
            tag.setTagName(tagParam.getTagName());
        }
        if (tagParam.getAvatar() != null){
            tag.setAvatar(tagParam.getAvatar());
        }
        int i = tagMapper.insert(tag);
        if (i > 0){
            return Result.success(null);
        }else {
            return Result.fail(ErrorCode.ADMIN_ERROR, "添加标签失败");
        }
    }

    @Override
    public Result deleteTag(Long id) {
        //删除前考虑所属文章，如果没有则直接删除
        LambdaQueryWrapper<ArticleTag> articleTagWrapper = new LambdaQueryWrapper<>();
        articleTagWrapper.eq(ArticleTag::getTagId, id);
        List<ArticleTag> articleTags = articleTagMapper.selectList(articleTagWrapper);

        //如果某篇文章只有这一个需要删除的标签则添加一个“其他”标签，否则直接删除该条记录
        //先判断是否存在“其他标签”
        LambdaQueryWrapper<Tag> tagWrapper = new LambdaQueryWrapper<>();
        tagWrapper.eq(Tag::getTagName, "其他");
        List<Tag> tags = tagMapper.selectList(tagWrapper);
        Long newTagId = null;
        if (tags == null || tags.size() <= 0){
            //创建“其他”标签
            Tag tag = new Tag();
            tag.setTagName("其他");
            //tag.setAvatar();
            tagMapper.insert(tag);
            newTagId = tag.getId();
        }else {
            newTagId = tags.get(0).getId();
            //排除删除“其他”情况
            if (id.equals(newTagId)){
                return Result.fail(ErrorCode.ADMIN_ERROR, "禁止删除‘其他’标签");
            }
        }

        //这个集合内的都是用到指定删除标签的文章
        for (ArticleTag articleTag : articleTags) {
            articleTagWrapper = new LambdaQueryWrapper<>();
            articleTagWrapper.eq(ArticleTag::getArticleId, articleTag.getArticleId());
            List<ArticleTag> temList = articleTagMapper.selectList(articleTagWrapper);
            if (temList.size() < 2){
                //只有一个，添加‘其他’标签
                ArticleTag articleTag1 = new ArticleTag();
                articleTag1.setArticleId(articleTag.getArticleId());
                articleTag1.setTagId(newTagId);
                articleTagMapper.insert(articleTag1);
            }
        }

        //删除articleTag
        articleTagWrapper = new LambdaQueryWrapper<>();
        articleTagWrapper.eq(ArticleTag::getTagId, id);
        articleTagMapper.delete(articleTagWrapper);

        int res = -1;
        //删除tag
        res = tagMapper.deleteById(id);

        if (res > 0){
            return Result.success(null);
        }else {
            return Result.fail(ErrorCode.ADMIN_ERROR, "删除标签失败");
        }
    }

    @Override
    public Result deleteTagList(Long[] arr) {
        if (arr == null || arr.length <= 0){
            return Result.fail(ErrorCode.ADMIN_ERROR, "批量删除数据为空");
        }
        int success = 0, fail = 0;
        for (Long aLong : arr) {
            Result result = deleteTag(aLong);
            if (result.isSuccess()){
                success++;
            }else {
                fail++;
            }
        }
        if (success == 0){
            return Result.fail(ErrorCode.ADMIN_ERROR, "批量删除失败");
        }else if (fail == 0){
            return Result.success(null);
        }else {
            return Result.fail(ErrorCode.ADMIN_ERROR, "批量删除部分失败");
        }
    }
}
